﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using CncConvProg.Model;
using CncConvProg.Model.FileManageUtility;
using CncConvProg.Model.ThreadTable;
using CncConvProg.Model.Tool;
using CncConvProg.Model.Tool.Drill;
using CncConvProg.Model.Tool.LatheTool;
using CncConvProg.Model.Tool.Mill;
using CncConvProg.ViewModel.CommonViewModel.ToolViewModels;
using CncConvProg.ViewModel.EditWorkDialog.TreeViewViewModel;
using CncConvProg.ViewModel.MainViewModel;
using CncConvProg.ViewModel.MVVM_Library;

namespace CncConvProg.ViewModel.Dialog
{
    /*
     * 
     */
    public class UtensiliDialogoViewModel : ViewModelBase, IDialog
    {
        private MagazzinoUtensile _magazzinoUtensile;
        private readonly MeasureUnit _measureUnit;

        public UtensiliDialogoViewModel(MeasureUnit measureUnit)
        {
            _measureUnit = measureUnit;
            _magazzinoUtensile = Singleton.Data.GetMagazzinoUtensile();

            UpdateTreeView();

            MaterialeSelezionato = Materiali.FirstOrDefault();
        }

        private ToolTreeViewItemViewModel _utensileSelezionato;
        public ToolTreeViewItemViewModel UtensileSelezionato
        {
            get { return _utensileSelezionato; }
            set
            {
                _utensileSelezionato = value;

                // Cambio parametro selezionato all'utensile
                if (_utensileSelezionato != null && MaterialeSelezionato != null)
                {
                    var t = _utensileSelezionato.Tool;
                    t.SelectParameter(MaterialeSelezionato.MaterialeGuid);
                }

                OnPropertyChanged("UtensileSelezionato");
            }
        }

        private ObservableCollection<TreeViewItemViewModel> _treeView = new ObservableCollection<TreeViewItemViewModel>();
        public ObservableCollection<TreeViewItemViewModel> TreeView
        {
            get { return _treeView; }

            set
            {
                _treeView = value;
                OnPropertyChanged("TreeView");
            }
        }


        private Materiale _materialeSelezionato;
        public Materiale MaterialeSelezionato
        {
            get
            {
                return _materialeSelezionato;
            }

            set
            {
                _materialeSelezionato = value;

                if (_utensileSelezionato != null && MaterialeSelezionato != null)
                {
                    var t = _utensileSelezionato.Tool;
                    t.SelectParameter(MaterialeSelezionato.MaterialeGuid);
                    _utensileSelezionato.UpdateParameterViewModel();
                }

                OnPropertyChanged("MaterialeSelezionato");

            }
        }

        public ObservableCollection<Materiale> Materiali
        {
            get
            {
                var mat = _magazzinoUtensile.GetMaterials(_measureUnit);

                return mat != null ? new ObservableCollection<Materiale>(mat) : new ObservableCollection<Materiale>();
            }
        }

        readonly Dictionary<Type, string> _toolDictName = new Dictionary<Type, string> 
                                   {
                                       {typeof (Punta), MecPrev.Resources.GuiRes.Drill},
                                       {typeof (Svasatore), MecPrev.Resources.GuiRes.Chamfer},
                                       {typeof (Alesatore), MecPrev.Resources.GuiRes.Reamer},
                                       {typeof (Centrino), MecPrev.Resources.GuiRes.CenterDrill},
                                       {typeof (Lamatore), MecPrev.Resources.GuiRes.Counterbore},
                                       {typeof (Bareno), MecPrev.Resources.GuiRes.Bore},
                                       {typeof (Maschio), MecPrev.Resources.GuiRes.Tap},

                                       {typeof (FresaCandela), MecPrev.Resources.GuiRes.Mill},
                                       {typeof (FresaSpianare), MecPrev.Resources.GuiRes.FaceMill},
                                       {typeof (FresaFilettare), MecPrev.Resources.GuiRes.ThreadMill},

                                       {typeof (UtensileTornitura), MecPrev.Resources.GuiRes.TurnTool},
                                       {typeof (UtensileScanalatura), MecPrev.Resources.GuiRes.TurnGroove},
                                       {typeof (UtensileFilettare), MecPrev.Resources.GuiRes.TurnThread},
                                   };

        /// <summary>
        /// Riaggiorna treeview, 
        /// per riaggiornare treeview, e per lasciare invariati 
        /// </summary>
        private void UpdateTreeView()
        {
            var previousTreeView = TreeView;

            var newTreeView = new ObservableCollection<TreeViewItemViewModel>();

            var ts = _magazzinoUtensile.GetTools<Utensile>(_measureUnit);

            var tipies = from t in ts
                         group t by t.GetType()
                             into tg
                             select tg;

            foreach (var tipy in tipies)
            {
                string groupName;

                _toolDictName.TryGetValue(tipy.Key, out groupName);

                var toolTypeTreeView = new ToolTypeItemViewModel(groupName);

                toolTypeTreeView.OnItemSelected += OnItemSelected;

                newTreeView.Add(toolTypeTreeView);

                foreach (var utensile in tipy)
                {
                    var t = ToolTreeViewItemViewModel.GetViewModel(utensile, toolTypeTreeView);

                    t.OnItemSelected += OnItemSelected;

                    toolTypeTreeView.Children.Add(t);
                }
            }

            /*
             * Ora itero vecchio albero per mantenere struttura,
             * 
             */

            foreach (var treeViewItemViewModel in previousTreeView)
            {
                foreach (var toolTypeItemViewModel in newTreeView)
                {
                    if (treeViewItemViewModel.Label == toolTypeItemViewModel.Label && treeViewItemViewModel.IsExpanded)
                    {
                        toolTypeItemViewModel.IsExpanded = true;

                        var oldChildren = treeViewItemViewModel.Children.OfType<ToolTreeViewItemViewModel>();
                        var newChildre = toolTypeItemViewModel.Children.OfType<ToolTreeViewItemViewModel>();

                        foreach (var oldChild in oldChildren)
                        {
                            if (oldChild.IsExpanded)
                                foreach (var newChild in newChildre)
                                {
                                    if (oldChild.Tool.ToolGuid == newChild.Tool.ToolGuid)
                                    {
                                        newChild.IsExpanded = true;
                                    }
                                }
                        }

                    }
                }
            }

            TreeView = newTreeView;
        }

        void OnItemSelected(object sender, EventArgs e)
        {
            UtensileSelezionato = sender as ToolTreeViewItemViewModel;
        }

        #region Add Tool

        RelayCommand _addToolCmd;
        /// <summary>
        /// Salva modifiche database
        /// </summary>
        private void AddTool(ToolTypeEnum toolType)
        {
            Utensile tool = null;
            switch (toolType)
            {
                case ToolTypeEnum.Punta:
                    {
                        tool = new Punta(_measureUnit);
                    } break;
                case ToolTypeEnum.Centrino:
                    {
                        tool = new Centrino(_measureUnit);
                    } break;
                case ToolTypeEnum.Svasatore:
                    {
                        tool = new Svasatore(_measureUnit);
                    } break;
                case ToolTypeEnum.Lamatore:
                    {
                        tool = new Lamatore(_measureUnit);
                    } break;
                case ToolTypeEnum.Bareno:
                    {
                        tool = new Bareno(_measureUnit);
                    } break;
                case ToolTypeEnum.Maschio:
                    {
                        tool = new Maschio(_measureUnit);
                    } break;

                case ToolTypeEnum.FresaCandela:
                    {
                        tool = new FresaCandela(_measureUnit);
                    } break;

                case ToolTypeEnum.Alesatore:
                    {
                        tool = new Alesatore(_measureUnit);
                    } break;

                case ToolTypeEnum.FresaSpianare:
                    {
                        tool = new FresaSpianare(_measureUnit);
                    } break;

                case ToolTypeEnum.UtensileTornitura:
                    {
                        tool = new UtensileTornitura(_measureUnit);
                    } break;

                case ToolTypeEnum.UtensileTornituraScanalatura:
                    {
                        tool = new UtensileScanalatura(_measureUnit);
                    } break;

                case ToolTypeEnum.UtensileTornituraFilettare:
                    {
                        tool = new UtensileFilettare(_measureUnit);
                    } break;

                default:
                    throw new NotImplementedException("UtViewModel.AddTool");

            }

            var guid = tool.ToolGuid;

            _magazzinoUtensile.SaveTool(tool);

            UpdateTreeView();

            foreach (var treeViewItemViewModel in _treeView)
            {
                foreach (var viewItemViewModel in treeViewItemViewModel.Children)
                {
                    var tvm = viewItemViewModel as ToolTreeViewItemViewModel;

                    if (tvm != null)
                    {
                        if (tvm.ToolGuid == guid)
                        {
                            tvm.IsSelected = true;
                            break;
                        }
                    }
                }
            }
        }

        public ICommand NewToolCmd
        {
            get
            {
                return _addToolCmd ?? (_addToolCmd = new RelayCommand(param => AddTool((ToolTypeEnum)param),
                                                                                param => true));
            }
        }

        #endregion

        #region Del Tool

        RelayCommand _delToolCmd;
        /// <summary>
        /// Salva modifiche database
        /// </summary>
        private void DelTool(ToolTreeViewItemViewModel toolType)
        {
            if (toolType == null) return;

            var t = toolType.Tool;

            _magazzinoUtensile.RemoveTool(t);

            UpdateTreeView();

        }

        public ICommand DelToolCmd
        {
            get
            {
                return _delToolCmd ?? (_delToolCmd = new RelayCommand(param => DelTool(param as ToolTreeViewItemViewModel),
                                                                               param => true));
            }
        }

        #endregion


        public void Save(IMainViewModel mainViewModel)
        {
            Singleton.Data.SaveMagazzino(_magazzinoUtensile);
        }

        //DelTool

        #region Add Tool

        RelayCommand _resetStoreCmd;
        private void ResetStoreCmd()
        {
            var msg = MessageBox.Show("Reset Tool Store ?", "Reset Tool Store", MessageBoxButton.YesNo,
                                                     MessageBoxImage.Warning, MessageBoxResult.None);

            if (msg != MessageBoxResult.Yes) return;

            _magazzinoUtensile = new MagazzinoUtensile();

            OnPropertyChanged("Materiali");
            UpdateTreeView();
        }

        public ICommand ResetToolStoreCmd
        {
            get
            {
                return _resetStoreCmd ?? (_resetStoreCmd = new RelayCommand(param => ResetStoreCmd(),
                                                                                param => true));
            }
        }

        #endregion

    }

    public enum ToolTypeEnum
    {
        FresaCandela,
        FresaSpianare,

        // Drill Type
        Punta,
        Alesatore,
        Svasatore,
        Bareno,
        Maschio,
        Lamatore,
        Centrino,

        /* Utensili Tornitura */
        UtensileTornitura,
        UtensileTornituraScanalatura,
        UtensileTornituraFilettare,

    }
    public class ToolTypeItemViewModel : TreeViewItemViewModel
    {
        public ToolTypeItemViewModel(string label)
            : base(label, null)
        {

        }


    }
}
